<template>
  <div class="sign-page">
    <!-- 上部分 -->
    <div class="header">
      <div class="header-left  flex gap-6 items-center">
        <div class="title-header">数据标注</div>
        <div class="info">
          <span style="color:#808899;">数据ID: 123</span>
          <span>(已标注)</span>
          <el-button link :icon="QuestionFilled" @click="showDetailDialog = true"></el-button>
        </div>
        <div class="mode">
          <div class="custom-tag annotation-mode">标注模式</div>
          <div class="custom-tag review-mode">复核模式</div>
          <div class="custom-tag read-mode">查看模式</div>
          <div class="custom-tag toExamine-mode">审核模式</div>
        </div>
      </div>
      <div class="action">
        <el-button type="primary" plain @click="versionVisiable = true">查看标注历史</el-button>
        <el-button type="primary">标注案例</el-button>
      </div>
    </div>

    <!-- 下部分 -->
    <div class="content">
      <div class="left">
        <div class="article">
          <div class="flex justify-between">
            <div class="flex gap-2 items-center pb-2">
              <span class="title-content">文本内容</span>
              <label>开始标注：</label>
              <el-switch size="small" v-model="markSwitch"></el-switch>
              <span v-if="markSwitch" class="flex items-center gap-2">
                <label>选择多段内容: </label>
                <input type="checkbox" id="multiSelect" v-model="multiSelect" />
              </span>
            </div>
            <div class="flex gap-2 justify-center items-center">
              <label>展示标签：</label>
              <el-switch v-model="tagsSwitch" size="small"></el-switch>
              <el-button type="primary" link @click="open">清空文本内容</el-button>
            </div>
          </div>

          <el-scrollbar style="height: calc(100% - 30px)">
            <div class="text-container" @click="handleTextContainerClick" @mousedown="startSelection"
              @mouseup="endSelection" ref="textContainer">
              <div ref="textParagraph"></div>
            </div>
          </el-scrollbar>
        </div>
        <div class="flex justify-center">
          <el-pagination layout="prev, pager, next" :total="totalPages" :page-size="pageSize"
            v-model:current-page="currentPage" @current-change="handlePageChange" />
        </div>
      </div>
      <div class="right flex justify-between flex-col">
        <div>
          <div class="annotation-results">
            <div class="flex justify-between">
              <div class="title-content pb-2">标注结果 </div>
              <div class="flex gap-2">
                <span>
                  <span class="inline-block w-[10px] h-[10px] bg-[#00c193]"></span>
                  复核正确
                </span>
                <span>
                  <span class="inline-block w-[10px] h-[10px] bg-[#f15b5a]"></span>
                  复核错误
                </span>
                <span>
                  <span class="inline-block w-[10px] h-[10px] bg-[#e9f2ff]"></span>
                  未复核
                </span>
              </div>
            </div>
            <el-scrollbar style="height: calc(35vh)">
              <div style="height: 35vh;">
                <div>
                  <div class="sign-list">
                    <div class="sign-name-box">
                      <p class="sign-type-name">
                        默认标签-数据有效性
                        <el-tooltip class="box-item" effect="dark" content="默认数据为有效数据，可以更改为无效数据选择无效数据后，不能再进行数据标注"
                          placement="top">
                          <el-button link :icon="QuestionFilled"></el-button>
                        </el-tooltip>
                      </p>
                    </div>
                  </div>
                  <div>
                    <!-- 单选按钮 -->
                    <el-radio-group v-model="selectedOption" size="small">
                      <el-radio label="有效" value="有效" size="large">有效</el-radio>
                      <el-radio label="无效" value="无效" size="large">无效</el-radio>
                    </el-radio-group>
                  </div>
                </div>
                <div v-for="(item, index) in 3" class="tag">
                  <div class="sign-list">
                    <div class="sign-name-box">
                      <p class="sign-type-name">产品态度（单选、多选）</p>
                      <p class="result-count">(3个结果)</p>
                    </div>
                    <div class="option-box">
                      <div class="custom-tag review-error">
                        保证质量 <span class="option-count"> （2） </span>
                      </div>
                      <div class="custom-tag review-current">
                        保证质量 <span class="option-count"> （2） </span>
                      </div>
                      <div class="custom-tag review-not">
                        保证质量 <span class="option-count"> （2） </span>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </el-scrollbar>
          </div>
          <div class="annotation-form">
            <!-- <div v-if="markSwitch">
              <span>
                {{ '添加标签' }}
                <el-input v-model="label" placeholder="请输入标签"></el-input>
              </span>
              <div>
                <el-button @click="cancelSelection">取消</el-button>
                <el-button type="primary" @click="confirm"> 确认 </el-button>
              </div>
            </div> -->
            <div class="title-content pb-2">内容标注</div>
            <div class="grid grid-cols-3 gap-4" style="grid-template-columns: 3fr 2fr 5fr;">
              <div style="width: 100%;overflow: hidden;">
                <div>已选中内容</div>
                <div class="config-item select-text">
                  <el-scrollbar :height="280">
                    <div v-if="!multiSelect">
                      {{ activeSelection?.text }}
                    </div>
                    <div v-else>
                      <div v-for="sel in activeMultiSelection" :key="sel.id">
                        {{ sel?.text }}
                      </div>
                    </div>
                  </el-scrollbar>
                </div>
              </div>
              <div style="width: 100%;overflow: hidden;">
                <div>标签类型</div>
                <div class="config-item label-type">
                  <el-scrollbar :height="280">
                    <div :class="item.name === value ? 'tab-item select-menu' : 'tab-item'" v-for="item in labelOptions"
                      @click="() => value = item.name">
                      {{ item.name }}
                      <span>
                        {{ item.required }}
                      </span>
                    </div>
                  </el-scrollbar>
                </div>
              </div>
              <div style="width: 100%;overflow: hidden;">
                <div>标签（多选、单选、文本）</div>
                <div class="config-item select-type">
                  <!-- 单选、多选(存在互斥情况)、文本（存在字数限制），是否必填，标签选项，排序 -->
                  <el-scrollbar :height="260">
                    <!-- 多选 -->
                    <div>
                      <div v-for="item in labelOptions">
                        <div v-if="item.name === value">
                          <div v-for="(option, index) in item.optionsList" :key="index">
                            <!-- 单选 -->
                            <div v-if="item.inputType === 1">
                              <el-radio-group v-model="radio">
                                <el-radio :value="option.options">
                                  <div>
                                    <span>{{ option.options }}</span>
                                    <el-tooltip class="box-item" effect="dark" :content="option.comment"
                                      placement="top">
                                      <el-button link :icon="QuestionFilled"></el-button>
                                    </el-tooltip>
                                  </div>
                                </el-radio>
                              </el-radio-group>
                              <div v-if="radio === option.options">
                                <div>
                                  标注解释
                                </div>
                                <el-input resize="none" :autosize="{ minRows: 2 }" v-model="option.textarea"
                                  style="width: 100%" :rows="2" type="textarea" />
                              </div>
                            </div>
                            <!-- 多选 -->
                            <div v-if="item.inputType === 2">
                              <el-checkbox-group v-model="checkList">
                                <el-checkbox :label="option.options" :value="option.options">
                                  <div>
                                    <span>{{ option.options }}</span>
                                    <el-tooltip class="box-item" effect="dark"
                                      :content="option.comment === '' ? '无注释内容' : option.comment" placement="top">
                                      <el-button link :icon="QuestionFilled"></el-button>
                                    </el-tooltip>
                                  </div>
                                </el-checkbox>
                              </el-checkbox-group>
                              <div v-if="checkList.includes(option.options)">
                                <div>
                                  标注解释{{ option.textarea }}
                                </div>
                                <el-input resize="none" :autosize="{ minRows: 2 }" v-model="option.textarea"
                                  style="width: 100%" :rows="2" type="textarea" />
                              </div>
                            </div>

                            <!-- 文本 -->
                            <div v-if="item.inputType === 3">
                              <div>
                                标注解释
                                <el-tooltip class="box-item" effect="dark" :content="option.comment" placement="top">
                                  <el-button link :icon="QuestionFilled"></el-button>
                                </el-tooltip>
                              </div>
                              <el-input resize="none" :autosize="{ minRows: 10 }" v-model="option.textarea"
                                :maxlength="item.wordLimited" style="width: 100%" :rows="10" type="textarea" />
                            </div>
                          </div>

                        </div>
                      </div>
                    </div>
                  </el-scrollbar>
                </div>
              </div>
            </div>
            <div class="flex justify-end">
              <el-button type="primary">临时保存</el-button>
              <el-button type="primary">提交</el-button>
              <el-button type="primary">提交并标注下一条</el-button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 提示信息弹出框 -->
    <el-dialog v-model="showDetailDialog" title="数据详情" width="30%">
      <p>数据ID: 123</p>
      <p>数据状态: 标注中</p>
      <p>其他信息: ...</p>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showDetailDialog = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
    <el-drawer v-model="versionVisiable" title="标注历史" direction="rtl" size="50%">
      <el-table :data="versionList">
        <el-table-column label="版本" align="center" width="80">
          <template #default="scope">
            v{{ scope.row.versionId }}
          </template>
        </el-table-column>
        <el-table-column prop="time" label="保存时间" width="220" />
        <el-table-column label="操作人" align="center">
          <template #default="scope">
            <el-tooltip popper-class="popclass" effect="dark" :content="scope.row.username + ' ' + scope.row.roleName"
              placement="top">
              <div class="oneLine">{{ scope.row.username + ' ' + scope.row.roleName }}</div>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column property="labelCount" label="标签量" width="80" />
        <el-table-column label="操作" align="center">
          <template #default="scope">
            当前版本
          </template>
        </el-table-column>
      </el-table>
    </el-drawer>
  </div>
</template>

<script setup>
import { useRouter } from 'vue-router';
import { ref, onMounted, nextTick, computed, watch } from 'vue';
import { Chicken, QuestionFilled } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
const versionVisiable = ref(false)
// 标注历史
const versionList = ref([
  {
    "labelCount": 6,
    "roleName": "标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员,标注经理,标注员,标注审核员,大模型经理,管理员",
    "time": "2025-03-14 14:03:36",
    "username": "陈松青",
    "versionId": 1
  }
])
// 内容标注列表
const labelOptions = ref([
  {
    "optionsList": [
      {
        "options": "用户至上",
        "comment": "",
        "id": "358",
        "sort": "1"
      },
      {
        "options": "质量保证",
        "comment": "",
        "id": "359",
        "sort": "1"
      },
      {
        "options": "创新驱动",
        "comment": "",
        "id": "360",
        "sort": "1"
      },
      {
        "options": "持续改进",
        "comment": "",
        "id": "361",
        "sort": "1"
      }
    ],
    "typeSort": 2,
    "name": "产品态度",
    "inputType": 2,
    "type": "产品态度",
    "required": 0
  },
  {
    "optionsList": [
      {
        "options": "清晰表达",
        "comment": "",
        "id": "354",
        "sort": "1"
      },
      {
        "options": "积极倾听",
        "comment": "",
        "id": "355",
        "sort": "1"
      },
      {
        "options": "非言语沟通",
        "comment": "",
        "id": "356",
        "sort": "1"
      },
      {
        "options": "同理心交流",
        "comment": "",
        "id": "357",
        "sort": "1"
      }
    ],
    "typeSort": 12,
    "name": "沟通风格(必填)",
    "inputType": 1,
    "type": "沟通风格(必填)",
    "required": 0
  },
  {
    "optionsList": [
      {
        "options": "11111",
        "comment": "",
        "id": "609",
        "sort": null
      },
      {
        "options": "222222",
        "comment": "",
        "id": "611",
        "sort": null
      }
    ],
    "typeSort": 6,
    "name": "电饭锅和",
    "inputType": 1,
    "type": "电饭锅和",
    "required": 1
  },
  {
    "optionsList": [
      {
        "options": "22222",
        "comment": "",
        "id": "610",
        "sort": null
      }
    ],
    "typeSort": 5,
    "name": "222222",
    "inputType": 1,
    "type": "222222",
    "required": 1
  },
  {
    "optionsList": [
      {
        "options": "",
        "comment": "文本限制500字33311",
        "id": "487",
        "sort": null
      }
    ],
    "typeSort": 3,
    "name": "文本解答",
    "inputType": 3,
    "type": "文本解答",
    "required": 0,
    "wordLimited": 500
  }
])



const selectedOption = ref('有效')
const checkList = ref([])
const radio = ref(3)
const textarea = ref('')
const router = useRouter();
const value = ref('产品态度多选')

const menus = ref([{
  label: '产品态度多选',
  value: '产品态度多选',
  type: 'checkbox',
  options: [
    {
      label: '用户至上',
      value: '用户至上',
      textarea: '',
    },
    {
      label: '质量保证',
      value: '质量保证',
      textarea: '',
    },
  ]
},
{
  label: '沟通风格(必填)单选',
  value: '沟通风格(必填)单选',
  type: 'radio',
  options: [
    {
      label: '清晰表达',
      value: '清晰表达',
      textarea: '',
    },
    {
      label: '积极倾听',
      value: '积极倾听',
      textarea: '',
    },
  ]
}, {
  label: '文本解答',
  value: '文本解答',
  type: 'textarea',
  textarea: '',
}])

// 上部分数据
const showDetailDialog = ref(false);

// 下部分数据
const totalPages = ref(10);
const pageSize = ref(1);
const currentPage = ref(1);

const handlePageChange = (page) => {
  currentPage.value = page;
};

const open = () => {
  ElMessageBox.confirm(
    '该操作会清除所有标注和标签以及历史版本记录回到初始状态，确定继续操作吗?',
    '提示',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
    }
  )
    .then(() => {
      ElMessage({
        type: 'success',
        message: 'Delete completed',
      })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: 'Delete canceled',
      })
    })
}
const markSwitch = ref(false);
const tagsSwitch = ref(true);
const text = ref(
  '昨天，长三角G60科创服务生态体系启动暨G60科创之眼推介大会在上海松江举行。“长三角G60科创之眼”作为上海长三角G60科创经济发展集团有限公司（以下简称“G60科创集团”）首个重大建设项目，是承载上海市与长三角其他区域资源要素流动的重要链接节点，也是长三角面向世界的重要窗口，旨在打造千亿级的科创新地标。\n\n  此外，长三角G60科创服务生态体系将打造国际化、市场化、标准化、品牌化的服务产品，提供从产业规划、产业招商到产业运营、产业服务全链条一站式服务，加速培育新质生产力，助力构建全国统一大市场。\n\n  现代化新型产业社区活力绽放\n\n  “长三角G60科创之眼”项目是G60科创集团成立后的第一个重大项目。项目规划总面积约1100亩，建成后将提供85万平方米的产业研发办公体、38万平方米的商业综合体和12万平方米的人才公寓，构建长三角G60科创走廊创新策源主阵地、高端产业聚集地、科创企业加速地、创新人才首选地。\n\n  G60科创集团总裁助理谭楠介绍说，长三角G60科创之眼作为现代化新型产业社区，建筑简洁、轻盈、线条流畅，既体现科技感又展现艺术性。下一步，将促进从地标到场景、从产业到人、从载体到社群的转变，使G60科创之眼区域成为一个充满活力的产业集聚区。\n\n  当天，长三角G60科创之眼首发地块包括12栋独栋办公楼及3栋塔楼，不少科技型企业提前布局落子，签订投资意向。“优赛科创集团将依托G60科创走廊的地理优势与政策支持，进一步联动长三角区域服务体系，打破地域界限，构建一个高效联动的长三角区域科创服务体系。”优赛科创集团董事长王金华表示，作为入驻园区的首家企业，将与G60科创集团紧密携手，取得更多发展机遇。\n\n  值得一提的是，“长三角G60科创之眼”项目创造了“当年拿地、当年开工、当年封顶、当年几乎实现销售”的G60速度。迄今为止，G60科创集团总投资超过50亿元，资产规模超过100亿元。\n\n  科创服务生态体系持续升级\n\n  优化创新生态，启动长三角G60科创服务生态体系建设是G60科创集团发展的另一先手棋。据介绍，长三角G60科创走廊九城市贡献全国1/15的GDP，拥有全国1/7的高新技术企业和超过1/5的科创板上市企业以及1020万个市场主体。\n\n  长三角G60科创服务生态体系将推动服务标准化建设，打造科研创新平台、标准管理以及科研体系数字化的三合一体的创新体系，把“让企业在长三角市场份额的有效增长、企业成本有效降低、服务舒适度有效提高”作为核心，更好优化产业生态、创新生态、服务生态，构建跨区域协同共享的服务体系。\n\n  同时，长三角G60科创服务生态体系将探索挖掘ChatGPT等大模型在新媒体领域的应用，通过新媒体方式，将过往以文字为信息的输出方式转换为当前流行的短视频和图文的信息输出方式，以瀑布流的模式展现，并通过底层算法将企业/个人/货品/信息进行四维循环匹配，实现多维度信息的高效流通和产业链的高度整合。\n\n  G60科创集团党委书记、董事长由杨表示，将建立长三角G60企业和人才数据库，推动高质量信息快速流动，形成新质生产力的孵化器和加速器，并在此基础上，与金融机构一起探索无抵押信用与技术贷款，为企业发展提供全生命周期的金融服务。\n\n  据悉，G60科创集团与国资委深度合作，共同成立“长三角G60国际商贸服务中心”，为长三角企业的出海以及海外订单的接洽全面对接服务，同时，还将与深圳市珠海市合作试点，尝试推动长三角与大湾区的企业形成产业链、供应链、人才链的深度融合，打通两地企业协同发展、联动招商的大通道，推动构建国内统一大市场，实现科创要素在两地的自由流通。',
);
const annotations = ref([
  {
    text: '昨天，',
    label: '项目名称',
    range: null,
    id: '0-2-abc',
  },
  { text: '流动的重要性', label: '公司名称', range: null, id: '115-120-def' },
  {
    text: '上海市与长三角其他区域资源要素流动的重要链接节点，也',
    label: '8546',
    range: null,
    id: '100-125-def',
  },
]);
const multiSelect = ref(false);
const activeSelection = ref(null);
const activeMultiSelection = ref([]);
const textContainer = ref(null);
const textParagraph = ref(null);

const dialogVisible = ref(false);
const label = ref('');
const tagCounter = ref(0);
const confirm = () => {
  if (label.value && activeSelection.value) {
    // 没有开启多选的情况下
    if (!multiSelect.value) {
      activeSelection.value.label = label.value;
      let tagListStr = `tag-list${tagCounter.value++}`;
      activeSelection.value.tagList = tagListStr;
      annotations.value.push({ ...activeSelection.value });
      highlightRange(activeSelection.value.range, ['default', tagListStr]);
    } else {
      let tagListStr = `tag-list${tagCounter.value++}`;
      let minNum = null;
      activeMultiSelection.value.forEach((item, index) => {
        const [startOffset, endOffset] = item.id.split('-').map(Number);
        if (index === 0) {
          minNum = startOffset;
        } else {
          if (startOffset < minNum) {
            minNum = startOffset;
          }
        }
        item.label = label.value;
        item.tagList = tagListStr;
        annotations.value.push({ ...item });
        if (index === activeMultiSelection.value.length - 1) {
          // 高亮并传递标签位置
          highlightRange(item.range, ['default', tagListStr], minNum);
        } else {
          highlightRange(item.range, ['default', tagListStr]);
        }
      });
    }
  } else {
    // 提示框：完善label或者选取文本
    cancelSelection();
  }
  nextTick(() => {
    dialogVisible.value = false;
    label.value = '';
    activeSelection.value = null;
    activeMultiSelection.value = [];
  });
  console.log('标注列表', annotations.value);
};

const cancelSelection = () => {
  // 单选取消
  if (
    activeSelection.value &&
    activeSelection.value.id &&
    !multiSelect.value
  ) {
    removeSpanById(activeSelection.value.id);
  }
  // 多选取消
  if (activeMultiSelection.value.length > 0 && multiSelect.value) {
    activeMultiSelection.value.forEach((item) => {
      removeSpanById(item.id);
    });
  }
  nextTick(() => {
    dialogVisible.value = false;
    label.value = '';
    activeSelection.value = null;
    activeMultiSelection.value = [];
  });
};


const highlightRangeById = (annotation) => {
  const { id, tagList, label } = annotation;
  const [startOffset, endOffset] = id.split('-').map(Number);
  const container = textParagraph.value;
  const spans = container.querySelectorAll('.word-list');
  for (let index = 0; index < spans.length; index++) {
    const span = spans[index];
    if (index >= startOffset && index <= endOffset) {
      span.classList.add('default', tagList);
      if (index.toString() === startOffset.toString()) {
        span.setAttribute('data-title', label);
      }
    }
  }
};

const removeSpanById = (id, tagList = null) => {
  const [startOffset, endOffset] = id.split('-').map(Number);
  const container = textParagraph.value;
  const spans = container.querySelectorAll('.word-list');

  let flag = true;
  for (let index = 0; index < spans.length; index++) {
    const span = spans[index];
    // 删除的时候需要根据tagList进行判断,批量删除
    const info = Array.from(span.classList).find(
      (className) => className === tagList,
    );
    // 根据tagList删除
    if (info !== undefined) {
      if (flag) {
        span.removeAttribute('data-title');
        flag = false;
      }
      span.classList.remove('new-tag', tagList);

      const tagListClass = Array.from(span.classList).find((className) =>
        className.startsWith('tag-list'),
      );
      if (tagListClass === undefined) {
        span.classList.remove('default');
      }
    }

    // 根据id取消选中的待标记文本
    if (index >= startOffset && index <= endOffset) {
      // 删除default时，需要确定没有taglist标签了
      span.classList.remove('new-tag', tagList);
      if (index.toString() === startOffset.toString()) {
        // 删除指定属性data-title
        span.removeAttribute('data-title');
      }
      const tagListClass = Array.from(span.classList).find((className) =>
        className.startsWith('tag-list'),
      );

      if (tagListClass === undefined) {
        span.classList.remove('default');
      }
    }
  }
};

const wrapTextWithSpans = () => {
  const container = textParagraph.value;
  const textContent = container.textContent;
  const spans = textContent.split('').map((char, index) => {
    const span = document.createElement('span');
    span.className = `word-list word${index} word_${index}`;
    span.textContent = char;
    return span;
  });
  container.innerHTML = ''; // 清空容器
  for (let i = 0; i < spans.length; i++) {
    const span = spans[i];
    container.appendChild(span);
  }
};

const handleTextContainerClick = (event) => {
  const target = event.target;
  if (target.classList.contains('word-list')) {
    const tagList = Array.from(target.classList).find((className) =>
      className.startsWith('tag-list'),
    );
    if (tagList) {
      const arr = Array.from(target.classList).filter((className) =>
        className.startsWith('tag-list'),
      );
      const matchingAnnotations = annotations.value.filter((annotation) =>
        arr.includes(annotation.tagList),
      );

      if (matchingAnnotations.length > 1) {
        // 按 text 长度排序，长度短的在前
        matchingAnnotations.sort((a, b) => a.text.length - b.text.length);
      }
      // 高亮第一个匹配的 annotation
      if (matchingAnnotations.length > 0) {
        highlightSpansByTagList(matchingAnnotations[0].tagList);
      }
    }
    // else {
    //   highlightSpansByTagList(null);
    // }
  }
};

const highlightSpansByTagList = (tagList) => {
  const container = textParagraph.value;
  const spans = container.querySelectorAll('.word-list');
  for (let i = 0; i < spans.length; i++) {
    const span = spans[i];
    if (span.classList.contains(tagList)) {
      span.classList.add('highlight'); // 添加高亮类
    } else {
      span.classList.remove('highlight'); // 移除高亮类
    }
  }
};

const startSelection = (event) => {
  // 判断是否开启标注状态
  if (!markSwitch.value) return;
  // 判断是否单选状态时，是否已经有选择
  if (!multiSelect.value && activeSelection.value) {
    // 清空蓝色高亮
    console.log('清除蓝色高亮', activeSelection.value);
    const container = textParagraph.value;
    const spans = container.querySelectorAll('.word-list');
    for (let i = 0; i < spans.length; i++) {
      const span = spans[i];
      span.classList.remove('new-tag'); // 移除高亮类
    }
    // return;
  }
  // 清除yellow高亮
  highlightSpansByTagList(null);
  activeSelection.value = {
    text: '',
    label: '',
    range: null,
    id: null,
  };
  window.getSelection().removeAllRanges();
};

const endSelection = (event) => {
  if (!markSwitch.value) return;
  if (!multiSelect.value && activeSelection.value.id) {
    return;
  }
  if (activeSelection.value) {
    const selection = window.getSelection();
    if (selection.rangeCount > 0) {
      const range = selection.getRangeAt(0);
      const selectedText = range.toString();
      if (selectedText) {
        activeSelection.value.text = selectedText;
        activeSelection.value.range = range;
        activeSelection.value.id = generateUniqueId(range);
        highlightRange(range, ['new-tag']);
        // 判断是否是多选
        if (multiSelect.value) {
          // activeMultiSelection
          activeMultiSelection.value.push(activeSelection.value);
          console.log('multi', activeMultiSelection.value);
        } else {
          // dialogVisible.value = true;
        }
      }
    }
  }
};

const highlightRange = (range, classNames, showTitlePosition = null) => {
  const startOffset =
    range.startContainer.parentNode.classList[2].split('_')[1];
  const endOffset = range.endContainer.parentNode.classList[2].split('_')[1];
  const container = textParagraph.value;
  const spans = container.querySelectorAll('.word-list');

  let pos = showTitlePosition === null ? startOffset : showTitlePosition; //标签位置
  for (let i = 0; i < spans.length; i++) {
    const span = spans[i];
    if (i >= startOffset && i <= endOffset) {
      span.classList.add(...classNames);
      if (classNames.includes('default')) {
        span.classList.remove('new-tag');
        if (i.toString() === pos.toString() && !multiSelect.value) {
          span.setAttribute('data-title', activeSelection.value.label);
        }
      }
    }
    // 多选时设置标签位置
    if (
      showTitlePosition !== null &&
      i.toString() === showTitlePosition.toString() &&
      multiSelect.value
    ) {
      span.setAttribute('data-title', activeSelection.value.label);
    }
  }
};

const removeAnnotation = (index, tagList) => {
  const annotation = annotations.value.splice(index, 1)[0];
  const filteredAnnotations = annotations.value.filter(
    (item) => item.tagList !== tagList,
  );
  annotations.value = filteredAnnotations;
  // console.log(9999, filteredAnnotations);
  if (annotation && annotation.id) {
    highlightSpansByTagList(null); //移除高亮
    removeSpanById(annotation.id, annotation.tagList);
  } else {
    console.log('No valid annotation or range to remove');
  }
};

const generateUniqueId = (range) => {
  const startOffset =
    range.startContainer.parentNode.classList[2].split('_')[1];
  const endOffset = range.endContainer.parentNode.classList[2].split('_')[1];
  const randomChar = Math.random().toString(36).substr(2, 3);
  return `${startOffset}-${endOffset}-${randomChar}`;
};

watch(() => multiSelect.value, (val) => {
  if (val && activeSelection.value && activeSelection.value.id) {//开启多选
    activeMultiSelection.value.push(activeSelection.value)
  } else {
    // 清空蓝色高亮
    const container = textParagraph.value;
    const spans = container.querySelectorAll('.word-list');
    for (let i = 0; i < spans.length; i++) {
      const span = spans[i];
      span.classList.remove('new-tag'); // 移除高亮类
    }
    activeMultiSelection.value = []
    activeSelection.value = null
  }
}, {})
onMounted(() => {
  textParagraph.value.textContent = text.value; // 确保文本内容插入到DOM中
  wrapTextWithSpans();
  annotations.value = annotations.value.map((annotation) => {
    return {
      ...annotation,
      tagList: `tag-list${tagCounter.value++}`,
    };
  });
  nextTick(() => {
    for (let i = 0; i < annotations.value.length; i++) {
      const annotation = annotations.value[i];
      highlightRangeById(annotation);
    }
  });
});
</script>

<style lang="scss" scoped>
.sign-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  padding: 0px 40px;
  background-color: #f1f5fb !important;

  .title-header {
    font-size: 20px;
    font-weight: bold;
    color: #454c5c;
  }

  .title-content {
    font-size: 18px;
    font-weight: bold;
  }

  .header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 40px;
    background-color: #fff;
    border-bottom: 1px solid #ebeef5;
    border-radius: 0 0 40px 40px;
    height: 70px;
    min-width: 1000px;
    box-shadow: 0 15px 30px #3370ff1f;

    .header-left {
      .info {
        display: flex;
        align-items: center;

        span {
          margin-right: 10px;
        }
      }

      .mode {
        margin-right: 10px;
      }
    }


    .action {
      display: flex;
      align-items: center;
    }
  }

  .content {
    display: flex;
    flex: 1;
    padding: 20px 0;
    min-width: 1000px;

    .left {
      flex: 3;
      margin-right: 10px;
      // border: 1px solid #ebeef5;
      background-color: #fff;
      border-radius: 25px;
      padding: 10px;

      .el-pagination {
        margin-bottom: 10px;
      }

      .article {
        padding: 10px;
        height: calc(100vh - 200px);
        overflow-y: hidden;
        margin-bottom: 20px;
      }
    }

    .right {
      flex: 2;
      margin-left: 10px;
      background-color: #fff;
      border-radius: 25px;
      padding: 10px;

      .annotation-results {
        padding: 10px;

        h3 {
          margin-bottom: 10px;
        }

        .tag {
          .flex {
            flex-wrap: wrap;
            /* 允许子元素换行 */
          }

          .el-tag {
            margin-bottom: 10px;
            /* 为每个标签添加底部间距 */
          }
        }
      }

      .annotation-form {
        padding: 10px;
        // 加上右侧边框

        .config-item {
          line-height: 1.5;
          padding: 5px;
          margin: 10px 0px;
          width: 100%;
          word-wrap: break-word;
        }

        .select-text {
          border: 1px solid #dfdfdf;
          border-radius: 10px;
        }



        .tab-item {
          padding: 3px;
          color: black;
          cursor: pointer;
        }

        .label-type {
          border-right: 1px solid #dfdfdf;
        }

        .select-menu {
          color: rgb(0, 110, 255);
          // border-right: 6px solid rgb(0, 110, 255);
        }

        // .select-menu::after {
        //   content: "";
        //   display: inline-block;
        //   width: 5px;
        //   height: 15px;
        //   background: linear-gradient(180deg, #3370ff, #3370ff24);
        //   border-radius: 11px;
        //   margin-right: 6px;
        //   position: relative;
        //   top: 2px;
        // }

        .tab-item:hover {
          color: rgb(103, 167, 252);
        }

        .tab-item-click {
          color: blue;
        }

        .select-type {
          background-color: #f1f5fb;
          border-radius: 10px;
          padding: 10px 20px;
        }
      }
    }
  }
}

.mode {
  margin-right: 10px;
}

.custom-tag {
  display: inline-block;
  padding: 0px 14px;
  height: 38px;
  line-height: 40px;
  text-align: center;
  border-radius: 8px;
  margin: 4px;
  font-size: 14px;

  &.annotation-mode {
    height: 40px;
    width: 106px;

    color: #3370ff;
    background-color: #e9f2ff;
  }

  &.read-mode {
    height: 40px;
    width: 106px;
    color: #faad14;
    background-color: #fffbe6;
  }

  &.review-mode {
    height: 40px;
    width: 106px;
    color: #fc9845;
    background-color: #fff5ec;
  }

  &.toExamine-mode {
    height: 40px;
    width: 106px;
    color: #f15b5a;
    background-color: #fdeeee;
  }

  &.review-current {
    color: #00c193;
    background-color: #e5f8f4;
    margin: 0 6px 12px;
    cursor: pointer;
  }

  &.review-error {
    color: #f15b5a;
    background-color: #fdeeee;
    margin: 0 6px 12px;
    cursor: pointer;

  }

  &.review-not {
    color: #454c5c;
    background-color: #e9f2ff;
    margin: 0 6px 12px;
    cursor: pointer;
  }

}


.sign-list {
  .sign-name-box {
    display: flex;
    align-items: center;

    .sign-type-name {
      font-size: 16px;
      color: #454c5c;
      margin-right: 10px;
    }

    .sign-type-name::before {
      content: "";
      display: inline-block;
      width: 5px;
      height: 15px;
      background: linear-gradient(180deg, #3370ff, #3370ff24);
      border-radius: 11px;
      margin-right: 6px;
      position: relative;
      top: 2px;
    }

    .result-count {
      font-size: 16px;
      color: #3370ff;
    }
  }

  .option-box {
    margin-top: 10px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
  }
}

.text-container {
  padding-top: 30px;
  padding-right: 15px;
}

::v-deep .word-list {
  position: relative; // 确保伪元素相对于这个元素定位
  white-space: pre-wrap;
  line-height: 1.4;
}

::v-deep .word-list:before {
  content: attr(data-title);
  display: inline-block;
  width: 70px;
  line-height: 24px;
  text-align: center;
  color: #fff;
  background: #fc9845;
  border-radius: 6px;
  box-shadow: 0 6px 6px #00000014;
  position: absolute;
  left: 0;
  // transition: all ease 0.3s;
  top: -26px;
  font-size: 14px;
  height: 24px;
  opacity: v-bind('tagsSwitch ? 1 : 0'); // 初始状态隐藏
  pointer-events: none; // 确保伪元素不影响交互
}

::v-deep .default {
  background-color: orange;
  color: white;
}

::v-deep .new-tag {
  background-color: blue;
  color: white;
}

::v-deep .highlight {
  background-color: yellow; // 设置高亮颜色
  color: black;
  // background-color: blue;
  // color: white;
}



::v-deep .oneLine {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>

<style lang="scss">
.popclass {
  width: 600px !important;
}
</style>